home *** CD-ROM | disk | FTP | other *** search
- /* *****************************************************************
- * ProblemManager.c - Problem Management Routines *
- *****************************************************************
-
- ProblemManager( Cmd, TypeProblem, nodename, UniqueID, StatusLine )
- Cmd - One of ADD_PROBLEM, ADD_PRIMARY_PROBLEM, DELETE_PROBLEM
- TypeProblem - Name of TestName that Failed
- nodename - Textual Name of Node ( Not-necesarily unique )
- UniqueId - Usually an IP UniqueIDess or otherwise unique Problem ID
- StatusLine - If Cmd is UPDATE_PROBLEM
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <time.h>
- #include "ProblemManager.h" /* Problem Manager routine defines */
- #include "version.h"
- /*#define DEBUG 1 /* */
-
- static char *DefaultPingkyDir="."; /* Starting point in File System */
- static char *PingkyDir; /* Starting point in File System */
-
- static char Problem_File[100]; /* PROBLEM FILE path */
- static long ProblemFileLastUpdated; /* Last time PROBLEM.FILE was updated */
- struct ProblemType
- ProblemArray[MAXPROBLEMS];/* In Core version of existing problems*/
- int NumProblems=0;
-
- static char Log_File[100]; /* Where do we log things */
-
- static char Config_File[100]; /* Where does User Comment Out Nodes */
- static long ConfigFileLastUpdated; /* Last time Config File was accessed */
-
- static int ProblemFileChanged=0;
-
- /************************************************
- * FORWARD DECLARATION OF STATIC ROUTINES *
- ************************************************/
- static int Add_Problem_Entry();
- static int AddProblem();
- static int DelProblem();
- static void ReadConfigFile();
- static char *Comment();
- #ifdef STANDALONE
- char *programname;
- #endif
-
- /****************************************************************
- * Problem_Manager: *
- * Cmds: *
- * ADD_PROBLEM: Add a problem to the list *
- * ( If not already there ) *
- * ADD_PRIMARY_PROBLEM: Add a problem deleteing *
- * all other problems with this node *
- * DELETE_PROBLEM: Remove this problem *
- * ( if there is one ) *
- * UPDATE_PROBLEM: Update this problem's StatusLine*
- * ( if there is one ) *
- * CLAIM_PROBLEM: Claim this problem *
- * ( just like UPDATE PROBLEM ) *
- * *
- ****************************************************************/
- int Problem_Manager(Cmd,TypeProblem,nodename,UniqueID,StatusLine)
- int Cmd; /* Add_Problem, Del_Problem, Add_Problem_Primary*/
- char *TypeProblem; /* Type of Problem - string text */
- char *nodename; /* nodename of node we are reporting about */
- char *UniqueID; /* Unique Identifier for this node(like IP UniqueID)*/
- char *StatusLine; /* Status Line - if Cmd is UPDATE_PROBLEM */
- {
- int i,changed=0;
- char buffer[100];
- extern char *getenv();
- extern char *programname;
- long TimeNow;
- static int virgin=1;
-
- ProblemFileChanged=0; /* We haven't changed the PROBLEM.FILE this call */
- if ( virgin ) { /* Set-Up Config Files we will access */
- if ((PingkyDir=getenv("PINGKYDIR"))==NULL)
- PingkyDir=DefaultPingkyDir;
- strcpy(Problem_File,PingkyDir); strcat(Problem_File ,"/PROBLEM.FILE");
- strcpy(Log_File,PingkyDir); strcat(Log_File,"/problemlog");
- strcpy(Config_File,PingkyDir); strcat(Config_File,"/ProblemManager.config");
- /*sprintf(buffer,"%s: %s\n",programname,Version);
- printf(buffer);
- Log( buffer, Log_File );*/
- virgin=0;
- }
-
- /************ ReRead Config File if it has changed **********/
- if ( FileChanged( Config_File, &ConfigFileLastUpdated ) ) {
- ReadConfigFile( Config_File );
- FileChanged( Config_File, &ConfigFileLastUpdated );
- }
- /************* ReRead Problem File if it has changed **********/
- if ( FileChanged( Problem_File, &ProblemFileLastUpdated ) ) {
- NumProblems = ReadProblemFile( ProblemArray, Problem_File );
- FileChanged( Problem_File, &ProblemFileLastUpdated );
- ProblemFileChanged=1;
- }
- /****************** Handle Caller's Command *******************/
- switch( Cmd ) {
- case ADD_PRIMARY_PROBLEM:
- changed=0;
- for (i=0; i<NumProblems ; i++)
- if (strcmp(ProblemArray[i].UniqueID,UniqueID)==0)
- if (strcmp(ProblemArray[i].TestName,TypeProblem)!=0){
- ProblemArray[i].Name[0]='\0';
- changed=1;
- }
- if ( changed ) {
- WriteProblemFile( ProblemArray,Problem_File,NumProblems);
- NumProblems=ReadProblemFile(ProblemArray,Problem_File);
- ProblemFileChanged=1;
- }
- case ADD_PROBLEM:
- NumProblems=AddProblem(nodename,UniqueID,TypeProblem,
- ProblemArray,NumProblems);
- break;
- case DELETE_PROBLEM:
- NumProblems=DelProblem(nodename,UniqueID,TypeProblem,
- ProblemArray, NumProblems);
- break;
- case UPDATE_PROBLEM:
- case CLAIM_PROBLEM:
- i=Problem_Exists(UniqueID,TypeProblem,ProblemArray,NumProblems);
-
- if ( i != -1 ) {
- strncpy( ProblemArray[i].StatusLine, StatusLine, MAXSTATUSLINE-1 );
- ProblemArray[i].StatusLine[MAXSTATUSLINE-1]='\0';
- WriteProblemFile(ProblemArray,Problem_File,NumProblems);
- NumProblems=ReadProblemFile(ProblemArray,Problem_File);
- if ( Cmd == UPDATE_PROBLEM )
- sprintf(buffer," ^%s^%s^Operator Update: %s (%d mins elapsed)\n",
- ProblemArray[i].Name,ProblemArray[i].UniqueID,ProblemArray[i].StatusLine,(time(&TimeNow)-ProblemArray[i].TimeStamp)/60);
- else
- sprintf(buffer," ^%s^%s^Operator Claim: %s (%d mins elapsed)\n",
- ProblemArray[i].Name,ProblemArray[i].UniqueID,ProblemArray[i].StatusLine,(time(&TimeNow)-ProblemArray[i].TimeStamp)/60);
- Log(buffer,Log_File);
- ProblemFileChanged=1;
-
- }
- break;
- case CHECK:
- break;
- default:
- Log("Problem_Manager- invalid cmd type!\n");
- panic("Problem_Manager- invalid cmd type!\n");
- break;
- }
- return(ProblemFileChanged);
- }
-
-
- /**************************************************************************
- * Add_Problem_Entry: Add a problem to the Problem structure and to disk *
- * To Do: Open this file with the append flag *
- **************************************************************************/
- static int Add_Problem_Entry(Node,UniqueID,ProblemType,Problem, NumProblems)
- char *Node,*UniqueID,*ProblemType;
- struct ProblemType *Problem;
- int NumProblems;
- {
- time( &Problem[NumProblems].TimeStamp );
- strncpy( Problem[NumProblems].Name, Node, MAXNODENAME-1 );
- Problem[NumProblems].Name[MAXNODENAME-1]='\0';
- strncpy( Problem[NumProblems].UniqueID, UniqueID, MAXUNIQUEID-1 );
- Problem[NumProblems].UniqueID[MAXUNIQUEID-1]='\0';
- strncpy( Problem[NumProblems].TestName, ProblemType, MAXTESTNAME-1 );
- Problem[NumProblems].TestName[MAXTESTNAME-1]='\0';
- strncpy( Problem[NumProblems].StatusLine, Comment( Node ), MAXSTATUSLINE-1 );
- Problem[NumProblems].StatusLine[MAXSTATUSLINE-1]='\0';
- /* printf("Add_Problem_Entry: ADDING %lu %s %s %s_%s_%s %s\n",
- Problem[NumProblems].TimeStamp,_Day(Problem[NumProblems].TimeStamp),
- _Time(Problem[NumProblems].TimeStamp),
- Problem[NumProblems].Name,Problem[NumProblems].UniqueID,
- Problem[NumProblems].TestName, Problem[NumProblems].StatusLine);*/
- NumProblems++;
- WriteProblemFile( Problem , Problem_File, NumProblems );
- NumProblems=ReadProblemFile(ProblemArray,Problem_File);
- ProblemFileChanged=1;
- return( NumProblems );
- }
-
- /********************************************************************
- * AddProblem: Add a problem to the Problem File if necessary *
- * *
- * Variables: *
- * Node: The name of the node that is having problems. *
- * UniqueID: The IP UniqueIDess of the node that is having the problem *
- * Service: The service that is failing (PING,TELNET,etc) *
- * Problem_File: Name of the Problem File containing Problems *
- ********************************************************************/
- static int AddProblem(Node,UniqueID,Service,Problem,NumProblems)
- char *Node,*UniqueID;
- char * Service;
- struct ProblemType *Problem;
- int NumProblems;
- {
- char Event[100];
-
- if ( TestNode( Node ) ) {
- /* printf("ProblemManager: %s is a test node - not added\n",Node);*/
- return( NumProblems );
- }
- if ( Problem_Exists(UniqueID,Service,Problem,NumProblems) == -1 ) {
- sprintf(Event,"ADDING PROBLEM %s_%s_%s_%s\n",
- Node,UniqueID,Service,Comment(Node));
- Log(Event,Log_File);
- NumProblems=Add_Problem_Entry(Node,UniqueID,Service,Problem,NumProblems);
- }
- return( NumProblems );
- }
-
- /********************************************************************
- * DelProblem: Delete a problem in the Problem File if necessary *
- * *
- * Variables: *
- * Node: The name of the node that is now behaving. *
- * UniqueID: The IP UniqueIDess of the node that is behaving correctly *
- * Service: The service that works now (PING,TELNET,etc) *
- * Problem_File: Name of the Problem File containing Problems *
- ********************************************************************/
- static int DelProblem(Node,UniqueID,Service,Problem,NumProblems)
- char *Node,*UniqueID;
- char *Service;
- struct ProblemType *Problem;
- int NumProblems;
- {
- char Event[100];
- int index;
- long TimeNow;
-
- time(&TimeNow);
-
- if ( (index=Problem_Exists(UniqueID,Service,Problem,NumProblems)) != -1 ) {
- sprintf(Event,"DELETING PROBLEM %s_%s_%s (%d mins elapsed)\n",
- Problem[index].Name,
- Problem[index].UniqueID,
- Service,((TimeNow-Problem[index].TimeStamp)/60));
- Log(Event,Log_File);
- /* DELETE the problem */
- Problem[index].Name[0]='\0'; /* Mark this node invalid */
- WriteProblemFile(Problem,Problem_File,NumProblems);
- NumProblems=ReadProblemFile(Problem,Problem_File);
- ProblemFileChanged=1;
- }
- return( NumProblems );
- }
-
- /************************************************************************
- * AUTOMATIC STATUS MESSAGES / TEST NODE SECTION *
- ************************************************************************/
- #define MAXNOTES MAXNODES
- #define MAXCOMMENT 30
-
- static int NumConfig=0;
- struct ConfigType {
- char ICare;
- char Name[MAXNODENAME];
- char Comment[MAXCOMMENT];
- } Config[MAXNOTES];
-
- /****** ReadConfigFile - Default comments, and TestName Nodes ******/
- /* NODE COMMENT LINE FOR ALL TO SEE BEV */
- static void ReadConfigFile( Config_File )
- char *Config_File;
- {
- FILE *stream;
- char buffer[100];
- int i=0,j,k;
-
-
- if ((stream=fopen(Config_File,"r")) == NULL)
- panic("ReadConfig: config file unreadable!\n");
-
- while( ( fgets(buffer,sizeof(buffer),stream) != NULL) && ( i < MAXNOTES ) ) {
- if (buffer[0]=='#')
- continue;
- j=0;
- if ( buffer[j] == '*' ) { /* '*' in Col 1 means IGNORE */
- Config[i].ICare=0;
- j++;
- }
- else Config[i].ICare=1; /* No '*' means I Care &*/
- for(k=0; j<MAXNODENAME && !isspace(buffer[j]); j++,k++)
- Config[i].Name[k]=buffer[j];
- Config[i].Name[MAXNODENAME-1]='\0';
-
- for(j++,k=0; j<strlen(buffer) && k<MAXCOMMENT; k++,j++ )
- if ( isprint( buffer[j] ) )
- Config[i].Comment[k]=buffer[j];
- Config[i].Comment[ MAXCOMMENT-1 ] = '\0';
-
- /* printf("Name[%d]=%s Comment=%s ICare=%d\n",i,Config[i].Name,Config[i].Comment,Config[i].ICare);*/
- i++; /** Yea! We have a valid line **/
- }
- fclose(stream);
- NumConfig=i;
- }
-
- static int IsConfig( node )
- char *node;
- {
- int i;
-
- if (FileChanged(Config_File,&ConfigFileLastUpdated)) {
- ReadConfigFile( Config_File );
- FileChanged(Config_File,&ConfigFileLastUpdated);
- }
- for( i=0; i<NumConfig; i++ ) {
- if ( strcmp( Config[i].Name , node ) == 0 )
- if ( Config[i].ICare == 0 ) {
- return( -1 ); /* TestNode Machine -I don't care */
- }
- else return( i ); /* INDEX OF NODE */
- else;
- }
- return( -2 ); /* NODE NOT FOUND */
- }
-
- int TestNode( node )
- char *node;
- {
- if ( IsConfig( node ) == -1 ) return( 1 ); /* TestNode */
- else return( 0 ); /* Non-TestNode */
- }
-
- static char *Comment( node )
- char *node;
- {
- int i;
-
- if ( ( i=IsConfig( node ) ) == -2 ) {
- /*printf("No Comment for %s\n",node);*/
- return( "" );
- }
- else {
- /*printf("%s Comment=%s\n",node, Config[i].Comment );*/
- return( Config[i].Comment );
- }
- }
-
- #ifdef STANDALONE
- main(argc, argv)
- int argc;
- char *argv[];
- {
- programname=argv[0];
- Problem_Manager(ADD_PROBLEM,"PING","NODE1","NODE1ID",NULL);
- Problem_Manager(ADD_PROBLEM,"PING","NODE2","NODE2ID",NULL);
- Problem_Manager(ADD_PROBLEM,"PING","NODE3","NODE3ID",NULL);
- PrintProblems(NumProblems,ProblemArray);
- sleep(10);
- Problem_Manager(DELETE_PROBLEM,"PING","NODE2","NODE2ID",NULL);
- PrintProblems(NumProblems,ProblemArray);
- sleep(10);
- Problem_Manager(ADD_PRIMARY_PROBLEM,"DOWN","NODE1","NODE1ID",NULL);
- PrintProblems(NumProblems,ProblemArray);
- sleep(10);
- Problem_Manager(DELETE_PROBLEM,"PING","NODE3","NODE3ID",NULL);
- Problem_Manager(UPDATE_PROBLEM,"PING","NODE1","NODE1ID","AN UPDATE");
- PrintProblems(NumProblems,ProblemArray);
- }
- #endif
-